"""
Copyright © 2023 Walkline Wang (https://walkline.wang)
Gitee: https://gitee.com/walkline/micropython-ws2812-led-clock
"""
__version__ = '0.1.3'
__version_info__ = (0, 1, 3)
print('module runner version:', __version__)


#region import modules
import gc
from time import sleep
from machine import Pin, SoftI2C
from drivers.button import Button
from drivers.sd3078_lite import SD3078Lite

gc.threshold(4000)

try:
	from utils.utilities import Utilities
except ImportError:
	Utilities = __import__('utils/utilities').Utilities

try:
	from utils.wifihandler import WifiHandler
except ImportError:
	WifiHandler = __import__('utils/wifihandler').WifiHandler

try:
	from matrix.matrix_clock import MatrixClock
except ImportError:
	MatrixClock = __import__('matrix/matrix_clock').MatrixClock

gc.collect()
#endregion import modules


CONFIG = Utilities.import_config()


class Runner(object):
	def __init__(self):
		self.__sd3078 = None

		self.__buttons = Button(
			CONFIG.KEYS.KEY_LIST,
			click_cb=self.__buttons_click_cb,
			press_cb=self.__buttons_press_cb,
			timeout=2000,
			timer_id=1,
		)
		self.__iic = SoftI2C(
			scl=Pin(CONFIG.PINS.IIC_SCL),
			sda=Pin(CONFIG.PINS.IIC_SDA)
		)

		for device_addr in self.__iic.scan():
			if device_addr == SD3078Lite.IIC_ADDR:
				self.__sd3078 = SD3078Lite(self.__iic)

		self.__clock = MatrixClock(self.__sd3078, self.__iic)

		self.__wifi_connecting = False

	def start(self):
		try:
			if self.__sd3078.power_lost or not WifiHandler.is_wifi_configed():
				# RTC 芯片未经校时的话必须成功完成一次联网校时
				self.__wifi_connecting = True
				self.__clock.show_connecting_animation()

				if WifiHandler.STATION_CONNECTED == WifiHandler.set_sta_mode(timeout_sec=120):
					self.__clock.sync_time()
					self.__clock.stop()
					self.__clock.show_blink()
				else:
					Utilities.hard_reset()

			self.__sd3078.datetime() # 读取 RTC 芯片存储的时间并设置本地时间
			self.__clock.start()

			if WifiHandler.STATION_CONNECTED == WifiHandler.set_sta_mode(timeout_sec=30):
				self.__clock.sync_time()

			self.__wifi_connecting = False

			gc.collect()

			while True:
				sleep(1)
		except KeyboardInterrupt:
			if self.__clock:
				self.__clock.stop()
				self.__clock.__tasks.deinit()
			if self.__buttons: self.__buttons.deinit()

	def __buttons_click_cb(self, pin):
		print(f'Key {CONFIG.KEYS.KEY_MAP[pin]} clicked')

		if self.__wifi_connecting:
			return

		if pin == CONFIG.KEYS.KEY_1:
			if self.__clock.is_menu_mode:
				self.__clock.show_hide_menu(save=False)
			else:
				self.__clock.switch_power()
		elif pin == CONFIG.KEYS.KEY_2:
			if self.__clock.is_menu_mode:
				self.__clock.switch_menu()
			else:
				self.__clock.switch_display_mode()

	def __buttons_press_cb(self, time, pin):
		print(f'Key {CONFIG.KEYS.KEY_MAP[pin]} pressed {time} ms')

		if pin == CONFIG.KEYS.KEY_1:
			if self.__clock.is_menu_mode:
				self.__clock.show_hide_menu(save=False)
			else:
				try:
					__import__(WifiHandler.STA_CONFIG_IMPORT_NAME)
					WifiHandler.delete_sta_config_file()
				except ImportError:
					if WifiHandler.is_ble_mode():
						WifiHandler.output_wifi_mode_file()
					else:
						WifiHandler.delete_wifi_mode_file()

				self.__clock.stop()
				Utilities.hard_reset()
		elif pin == CONFIG.KEYS.KEY_2:
			if self.__wifi_connecting:
				return

			if self.__clock.__last_menu == MatrixClock.MODE_UPDATE:
				self.__clock.check_update()
			else:
				self.__clock.show_hide_menu()


if __name__ == '__main__':
	runner = Runner()
	runner.start()
